SpringCloud进阶之Ribbon和Feign(负载均衡)
Spring Cloud 进阶之Ribbon和Feign(负载均衡)
Ribbon 负载均衡
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端,负载均衡的工具;
Ribbon 核心组件IRule
根据特定算法,从服务列表中选取一个要访问的服务:
- RoundRobinRule:轮询
- RandomRule:随机
- AvailabilityFilteringRule: 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,以及并发的连接数量
超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问;
- WeightedResponseTimeRule: 根据平均响应时间计算所有服务的权重,响应时间越快,服务权重越大,被选中的机率越高;
刚启动时,如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够时,会切换到WeightedResponseTimeRule
- RetryRule: 先按照RoundRobinRule的策略获取服务,如果获取服务失败,则在指定时间内会进行重试,获取可用的服务;
- BestAvailableRule: 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务;
- ZoneAvoidanceRule: 默认规则,复合判断server所在区域的性能和server的可用性选择服务器;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| @Configuration public class ConfigBean { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
@Configuration public class ConfigBean {
@Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); }
@Bean public IRule myRule() { return new RoundRobinRule(); } }
@SpringBootApplication @EnableEurekaClient @RibbonClient(name="MICROSERVICECLOUD-DEPT", configuration=MySelfRule.class) public class DeptConsumer80_App {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer80_App.class, args); }
}
@Configuration public class MySelfRule{ @Bean public IRule myRule(){ return new RandomRule(); } }
|
Feign 负载均衡
Feign 是一个声明式WebService客户端:
使用方法: 定义一个接口,然后在上面添加注解;
- 首先通过 @EnableFeignClients 注解开启 FeignClient 的功能。只有这个注解存在,才会在程序启动时开启 @FeignClient 注解的包扫描。
- 根据Feign的规则实现接口,并在接口上面加上 @FeignClient 注解。
- 程序启动后,会进行包扫描,扫描所有的@FeignClient 的注解的类,并将这些信息注入 IOC容器中。
- 当接口的方法被调用时,通过JDK的代理来生成具体的 RequestTemplate 模板对象。
- 根据 RequestTemplate 再生成 Http 请求的 Request 对象。
- Request 对象交给 Client 去处理,其中 Client 的网络请求框架可以是 HTTPURLConnection、HttpClient 和 OkHttp。
- 最后Client被封装到LoadBalanceClient类,这个类结合类 Ribbon 做到了负载均衡。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @FeignClient(value="MICROSERVICECLOUD-DEPT") public interface DeptClientService {
@RequestMapping(value="/dept/get/{id}", method= RequestMethod.GET) public Dept get(@PathVariable("id") long id);
@RequestMapping(value="/dept/list", method= RequestMethod.GET) public List<Dept> list();
@RequestMapping(value="/dept/add", method= RequestMethod.POST) public boolean add(Dept dept); }
@RestController public class DeptController_Consumer {
@Autowired private DeptClientService service;
@RequestMapping(value="/consumer/dept/get/{id}") public Dept get(@PathVariable("id") Long id) { return this.service.get(id); }
@RequestMapping(value="/consumer/dept/list") public List<Dept> list(){ return this.service.list(); }
@RequestMapping(value="/consumer/dept/add") public Object add(Dept dept) { return this.service.add(dept); } }
|